

/******************************************************************************/


#ifdef __WIN32__

#include <winsock2.H>
#include <windows.h>

typedef int socklen_t;

#define LLD "I64d"

#else /************************************************************************/

#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

typedef int SOCKET;

#define INVALID_SOCKET	(SOCKET)(~0)

#define SD_RECEIVE SHUT_RD
#define SD_SEND    SHUT_WR
#define SD_BOTH    SHUT_RDWR

#define closesocket close

#define WSAGetLastError() errno
#define LLD "lld"

#endif


/******************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <pthread.h>


typedef unsigned  char  u8;
typedef unsigned short  u16;
typedef unsigned   int  u32;

typedef   signed  char  s8;
typedef   signed short  s16;
typedef   signed   int  s32;

typedef unsigned long long  u64;
typedef   signed long long  s64;


#define CLIENT_MODE  1
#define SERVER_MODE  2

#define RAWMODE_ICMP 1
#define RAWMODE_UDP  2
#define RAWMODE_FAKETCP 3

#define PORT_TCP 1
#define PORT_UDP 2


#define CLIENT_PROTO 0x08
#define SERVER_PROTO 0x00

#define PCODE_DATA       0x70
#define PCODE_MSG        0x71
#define PCODE_CONNECT    0x72
#define PCODE_DISCONNECT 0x73

struct global_cfg {
	int mtu;

	int run_mode;
	int raw_mode;
	int port_mode;

	char listen_ip[32];
	int  listen_port;

	char forward_ip[32];
	int  forward_port;

	char target_ip[32];
	int  target_port;

	char devname[32];
};

extern struct global_cfg gcfg;

/******************************************************************************/


void hex_dump(char *str, const void *buf, int size);
u64 get_ticks(void);

u16 ip_checksum(u16 *addr, int len);
int socket_nonblock(SOCKET skt);

/******************************************************************************/


#define EV_IN    1
#define EV_OUT   2
#define EV_TMOUT 4
#define EV_DEL   8

typedef struct evio_t {
	int fd;
	int flag;
	void *read_func;
	void *write_func;
	void *tmout_func;
	void *arg;
	struct evio_t *next;
}EVIO;


int evio_init(int timeout_val);
int evio_exit(void);
EVIO *evio_find(int fd);
int evio_add(int fd, void *read_func, void *write_func, void *tmout_func, void *arg);
int evio_del(int fd);
int evio_enable(int fd, int flag);
int evio_disable(int fd, int flag);
int evio_loop(void *tmout_func);


/******************************************************************************/


int rawio_init(void *recv_cb, void *arg);
int rawio_send(void *tun, const void *buf, int len);
int rawio_heartbeat(int ms);
void *rawio_listen_tun(void);


void *new_kcp_tunnel(void *itun, void *recv_cb, void *arg);
void kcp_input(void *tunnel, const void *buf, int len);
int kcp_send(void *tunnel, const void *buf, int len);
void close_kcp_tunnel(void *tunnel);

int run_tcp_server(void);
void close_tunnel_stream(void *tunnel);


/******************************************************************************/

